
"""
SQL Server 数据库连接和密码管理模块

此模块提供了与 SQL Server 数据库的连接和密码管理功能。主要用于自动化数据库用户密码的修改操作。

主要功能:
    1. 建立与 SQL Server 数据库的安全连接
    2. 使用 Windows 身份验证进行连接
    3. 修改指定用户的数据库密码
    4. 通过信号机制通知操作结果

依赖项:
    - pyodbc: 用于与 SQL Server 数据库建立连接
    - PyQt5.QtCore: 提供信号机制用于通知密码修改结果

安全说明:
    1. 使用 Windows 身份验证确保连接安全性
    2. 密码修改操作需要足够的权限
    3. 建议定期检查和更新 ODBC 驱动
    4. 确保数据库服务器防火墙配置正确

作者: Craft
版本: 1.0.0
"""

import pyodbc
from PyQt5.QtCore import pyqtSignal, QObject

class DatabaseConnection(QObject):
    """
    SQL Server 数据库连接管理类
    
    此类提供数据库连接和密码修改的功能，使用 Windows 身份验证确保连接安全。
    
    Attributes:
        password_changed_signal (pyqtSignal): 密码修改操作的结果信号
            - 参数1 (bool): 操作是否成功
            - 参数2 (str): 操作结果消息
        server (str): 数据库服务器地址
        database (str): 数据库名称
        username (str): 数据库用户名
    """
    
    password_changed_signal = pyqtSignal(bool, str)
    
    def __init__(self, server: str, database: str, username: str):
        """
        初始化数据库连接实例
        
        Args:
            server (str): 数据库服务器地址，例如 'localhost\\SQLEXPRESS'
            database (str): 数据库名称，例如 'master'
            username (str): 数据库用户名
            
        Raises:
            ValueError: 当任何参数为空或无效时抛出
        """
        super().__init__()
        
        # 验证参数
        if not server or not isinstance(server, str):
            raise ValueError("服务器地址不能为空且必须是字符串")
        if not database or not isinstance(database, str):
            raise ValueError("数据库名称不能为空且必须是字符串")
        if not username or not isinstance(username, str):
            raise ValueError("用户名不能为空且必须是字符串")
            
        self.server = server
        self.database = database
        self.username = username
    
    def change_password(self, new_password: str) -> bool:
        """
        修改数据库用户密码
        
        使用 Windows 身份验证连接到数据库并修改指定用户的密码。
        操作结果将通过 password_changed_signal 信号发出。
        
        Args:
            new_password (str): 新的密码，不能为空
            
        Returns:
            bool: 密码修改是否成功
            
        Raises:
            ValueError: 当密码为空时抛出
            
        Signal Emissions:
            password_changed_signal:
                - 成功时: (True, "密码修改成功")
                - 失败时: (False, "数据库密码修改失败: 具体错误信息")
        """
        if not new_password or not isinstance(new_password, str):
            raise ValueError("新密码不能为空且必须是字符串")
            
        conn = None
        cursor = None
        try:
            # 建立数据库连接
            conn = pyodbc.connect(
                f"DRIVER={{ODBC Driver 17 for SQL Server}};"
                f"SERVER={self.server};"
                f"DATABASE={self.database};"
                f"UID={self.username};"
                f"Trusted_Connection=yes"
            )
            cursor = conn.cursor()
            
            # 执行密码修改
            cursor.execute(f"ALTER LOGIN [{self.username}] WITH PASSWORD='{new_password}'")
            conn.commit()
            
            self.password_changed_signal.emit(True, "密码修改成功")
            return True
            
        except Exception as e:
            error_msg = f"数据库密码修改失败: {str(e)}"
            self.password_changed_signal.emit(False, error_msg)
            return False
            
        finally:
            # 确保资源正确关闭
            if cursor:
                cursor.close()
            if conn:
                conn.close()
    
    def test_connection(self) -> bool:
        """
        测试数据库连接是否可用
        
        Returns:
            bool: 连接测试是否成功
        """
        try:
            conn = pyodbc.connect(
                f"DRIVER={{ODBC Driver 17 for SQL Server}};"
                f"SERVER={self.server};"
                f"DATABASE={self.database};"
                f"UID={self.username};"
                f"Trusted_Connection=yes",
                timeout=5
            )
            conn.close()
            return True
        except Exception:
            return False